package biz.k11i.gdd2011.solver;

import java.util.ArrayList;
import java.util.List;

import biz.k11i.gdd2011.board.Board;
import biz.k11i.gdd2011.enums.MovingDirection;

public class PanelMovements {
    public static class Movement {
        private int destination;

        private MovingDirection direction;

        public Movement(int destination, MovingDirection direction) {
            this.destination = destination;
            this.direction = direction;
        }

        public final int destination() {
            return destination;
        }

        public final MovingDirection movingDirection() {
            return direction;
        }

        @Override
        public String toString() {
            return destination + ":" + direction;
        }
    }

    private List<List<Movement>> movements;

    public PanelMovements(Board board) {
        buildMovement(board);
    }

    private void buildMovement(Board board) {
        int width = board.width();
        int height = board.height();

        int size = width * height;

        movements = new ArrayList<List<Movement>>();

        for (int row = 0; row < height; row++) {
            int base = row * width;
            for (int col = 0; col < width; col++) {
                int index = base + col;

                List<Movement> m = new ArrayList<Movement>();
                if (!board.isWallPanel(index)) {
                    addDestinatioIfMovable(m, board, (index - width >= 0),
                            index - width, MovingDirection.UP);
                    addDestinatioIfMovable(m, board, (index + width < size),
                            index + width, MovingDirection.DOWN);
                    addDestinatioIfMovable(m, board, (col - 1 >= 0), index - 1,
                            MovingDirection.LEFT);
                    addDestinatioIfMovable(m, board, (col + 1 < width),
                            index + 1, MovingDirection.RIGHT);
                }

                movements.add(m);
            }
        }
    }

    private void addDestinatioIfMovable(List<Movement> result, Board board,
            boolean isInBoard, int destination, MovingDirection direction) {
        if (!isInBoard || board.isWallPanel(destination)) {
            return;
        }

        result.add(new Movement(destination, direction));
    }

    public final List<Movement> movements(int index) {
        return movements.get(index);
    }
}
